/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package webapi;

import com.inspur.edp.lcm.metadata.api.mvnEntity.MavenComponents;
import com.inspur.edp.lcm.metadata.api.mvnEntity.MetadataRepo;
import com.inspur.edp.lcm.metadata.api.mvnEntity.ModuleDependencies;
import com.inspur.edp.lcm.metadata.api.service.FileService;
import com.inspur.edp.lcm.metadata.api.service.MdpkgService;
import com.inspur.edp.lcm.metadata.api.service.MetadataProjectService;
import com.inspur.edp.lcm.metadata.devcommon.ManagerUtils;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.Model;
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;

/**
 * Description Maven引用设计时接口实现
 *
 * @version 1.0
 */
@Path("/")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class RepoRefWebApi {

    private MdpkgService mdpkgService;

    private MdpkgService getMdpkgService() {
        if (mdpkgService == null) {
            mdpkgService = SpringBeanUtils.getBean(MdpkgService.class);
        }
        return mdpkgService;
    }

    private FileService fileService;

    private FileService getFileService() {
        if (fileService == null) {
            fileService = SpringBeanUtils.getBean(FileService.class);
        }
        return fileService;
    }

    private MetadataProjectService metadataProjectService;

    private MetadataProjectService getMetadataProjectService() {
        if (metadataProjectService == null) {
            metadataProjectService = SpringBeanUtils.getBean(MetadataProjectService.class);
        }
        return metadataProjectService;
    }

    /**
     * 部署jar到nexus私服中。 step1:将元数据包打包中jar中。 step2:推送
     *
     * @param proPath 元数据工程路径
     * @param proPath 推送的仓库地址
     * @param version 工程的版本号
     * @param revert  版本号是否回退
     * @return void
     **/
    @POST
    public void deployMdpkg(@QueryParam(value = "proPath") String proPath,
        @QueryParam(value = "repoId") String repoId,
        @QueryParam(value = "version") String version,
        @DefaultValue("false") @QueryParam(value = "revert") boolean revert) throws IOException {
        getMdpkgService().deploySnapshotMdVersion(proPath, repoId, version, revert);
    }

    /**
     * @param path    gsp工程路径
     * @param version 工程版本号
     * @param repoId  仓库唯一id
     * @param revert  默认为true,即推送完release版，版本号revert回原版本
     */
    @POST
    @Path(value = "/release")
    public void deployReleaseMdVersion(@QueryParam(value = "path") String path,
        @QueryParam(value = "version") String version,
        @QueryParam(value = "repoId") String repoId,
        @DefaultValue("false") @QueryParam(value = "revert") boolean revert,
        @QueryParam(value = "depversion") String dependenciesVersion) throws IOException {
        getMdpkgService().deployReleaseMdVersion(path, version, repoId, revert, dependenciesVersion);
    }

    /***
     * 获取仓库列表
     *
     * @return com.inspur.edp.lcm.metadata.api.mvnEntity.MetadataRepo
     **/
    @GET
    @Path(value = "/repolist")
    public MetadataRepo getRepoList() {
        return getMdpkgService().getRepoList();
    }

    /**
     * 实现maven install
     *
     * @param path gsp工程路径
     **/
    @POST
    @Path(value = "/compile")
    public void compile(@QueryParam(value = "path") String path, @QueryParam(value = "modules") String modules) {
        String projPath = getMetadataProjectService().getProjPath(path);
        getMdpkgService().compile(projPath, modules);
    }

    /**
     * @param path
     * @param operations
     */
    @POST
    @Path(value = "/batchOperate")
    public void batchOperate(@QueryParam(value = "path") String path,
        @QueryParam(value = "operations") String operations) {
        List<String> operationList = Arrays.asList(operations.split(","));
        getMdpkgService().batchOperate(path, operationList);
    }

    /**
     * 实现maven install
     *
     * @param path gsp工程路径
     */
    @POST
    @Path(value = "/compileAll")
    public void compileAll(@QueryParam(value = "path") String path) {
        String projPath = getMetadataProjectService().getProjPath(path);
        getMdpkgService().compileAll(projPath);
    }

    /**
     * @param path 工程路径
     */
    @POST
    @Path(value = "/restore")
    public void restore(@QueryParam(value = "path") String path, @QueryParam(value = "force") Boolean force) {
        getMdpkgService().restore(path, force);
    }

    /**
     * 给工程添加依赖并拉取
     *
     * @param path             工程路径
     * @param metadataPackages 新添加的依赖的额元数据包
     */
    @PUT
    @Path(value = "/adddepedency")
    public void addDepedencyAndRestore(@QueryParam(value = "path") String path,
        @QueryParam(value = "metadataPackages") String metadataPackages) {
        String[] packages = metadataPackages.split(",");
        List<String> packageList = new ArrayList<>(Arrays.asList(packages));
        getMdpkgService().addDepedencyAndRestore(path, packageList);
    }

    @GET
    @Path(value = "/projversion")
    public ModuleDependencies getDependenciesVersion(@QueryParam(value = "path") String path) throws IOException {
        String absolutePath = ManagerUtils.getAbsolutePath(path);

        if (getFileService().getApiModulePath(absolutePath) == null) {
            throw new RuntimeException("代码未生成，请生成java代码");
        }
        String apiPath = getFileService().getApiModulePath(absolutePath) + "/pom.xml";
        List<Dependency> list;
        try (FileInputStream fis = new FileInputStream(apiPath)) {
            MavenXpp3Reader reader = new MavenXpp3Reader();
            Model model = reader.read(fis);
            list = model.getDependencies();
            ModuleDependencies dependencies = new ModuleDependencies();
            if (model.getVersion() != null) {
                dependencies.setProjVersion(model.getVersion());
            } else {
                dependencies.setProjVersion(model.getParent().getVersion());
            }
            for (Dependency dependency : list) {
                if (dependency.getVersion().endsWith("SNAPSHOT")) {
                    dependencies.setNeedChange(true);
                }
            }
            return dependencies;
        } catch (IOException | XmlPullParserException e) {
            e.printStackTrace();
        }
        return new ModuleDependencies();
    }

    @GET
    @Path(value = "/buildorder")
    public List<String> getBuildOrder(@QueryParam(value = "projPath") String projPath) {
        return getMetadataProjectService().getBuildOrder(projPath);
    }

    @GET
    @Path(value = "/single")
    public MavenComponents getVersionsOfSinglePackage(@QueryParam(value = "sourceId") String sourceId,
        @QueryParam(value = "packName") String packName) {
        return getMdpkgService().getVersionsOfSinglePackage(sourceId, packName);
    }

    @PUT
    @Path(value = "/install")
    public void installMdpkg(@QueryParam(value = "groupId") String groupId,
        @QueryParam(value = "artifactId") String artifactId, @QueryParam(value = "version") String version,
        @QueryParam(value = "path") String path) throws IOException {
        Boolean forceUpdateFlag = version.contains("-") ? true : false;
        getMdpkgService().installMdpkg(groupId, artifactId, version, path, forceUpdateFlag);
    }

    @POST
    @Path(value = "/uninstall")
    public void uninstallMdpkg(@QueryParam(value = "projPath") String projPath,
        @QueryParam(value = "packName") String packName) {
        getMdpkgService().uninstallMdpkg(projPath, packName);
    }
}
